package com.itstyle.quartz.web;


import java.util.*;

import javax.servlet.http.HttpServletResponse;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.itstyle.quartz.entity.QuartzEntity;
import com.itstyle.quartz.entity.Result;
import com.itstyle.quartz.service.IJobService;

@RestController
@RequestMapping("/job")
public class JobController {
    private final static Logger LOGGER = LoggerFactory.getLogger(JobController.class);


    @Autowired
    private Scheduler scheduler;
    @Autowired
    private IJobService jobService;

    @SuppressWarnings({"unchecked", "rawtypes"})
    @PostMapping("/add")
//	@ApiImplicitParams({
    @ApiOperation(value = "新建定时任务", notes = "根据quartz对象创建定时任务")
    @ApiImplicitParam(name = "quartz", value = "定时任务实体类", required = true, dataType = "QuartzEntity")
//	,@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
//	})
    public Result save(QuartzEntity quartz) {
        LOGGER.info("新增任务");
        try {
            //如果是修改  展示旧的 任务
            JobKey key = new JobKey(quartz.getJobName(), quartz.getJobGroup());
            scheduler.deleteJob(key);
            //            jobDataMap 参数
            JobDataMap jobDataMap = new JobDataMap();
            List<Map<String, Object>> jobDataMapList = quartz.getJobDataMapList();
            for (Map<String, Object> map : jobDataMapList) {
                String mapKey = (String) map.get("key");
                String mapValue = (String) map.get("value");
                if (StringUtils.isNotBlank(mapKey) && StringUtils.isNotBlank(mapValue)) {
                    jobDataMap.put(mapKey, mapValue);
                }
            }
            Class cls = Class.forName(quartz.getJobClassName());
            cls.newInstance();
            //构建job信息
            JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(),
                    quartz.getJobGroup())
                    .withDescription(quartz.getDescription()).build();
            // 触发时间点
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger" + quartz.getJobName(), quartz.getJobGroup())
                    .startNow().withSchedule(cronScheduleBuilder).usingJobData(jobDataMap).build();
            //交由Scheduler安排触发
            scheduler.scheduleJob(job, trigger);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }

    @PostMapping("/list")
    @ApiOperation(value = "查看定时任务列表", notes = "")
    @ApiImplicitParam(name = "quartz", value = "定时任务实体类", required = true, dataType = "QuartzEntity")
    public Result list(QuartzEntity quartz, Integer pageNo, Integer pageSize) {
        LOGGER.info("任务列表");
//        List<QuartzEntity> list = jobService.listQuartzEntity(quartz, pageNo, pageSize);
        List<QuartzEntity> jobList = new ArrayList<>();
        JobDetail jobDetail = null;
        List<Map<String, Object>> jobDataMapList = new ArrayList<>();
        try {
            GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
            Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
            for (JobKey jobKey : jobKeys) {
                jobDetail = scheduler.getJobDetail(jobKey);
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
                for (Trigger trigger : triggers) {
                    JobDataMap jobDataMap = trigger.getJobDataMap();
                    Map<String, Object> jobMap = new HashMap<>();
                    for (Map.Entry<String, Object> entry : jobDataMap.entrySet()) {
                        jobMap.put(entry.getKey(), entry.getValue());
                        Map<String, Object> jobMap1 = new HashMap<>();
                        jobMap1.put("key", entry.getKey());
                        jobMap1.put("value", entry.getValue());
                        jobDataMapList.add(jobMap1);
                    }
                    QuartzEntity job = new QuartzEntity();
                    job.setJobName(jobKey.getName());
                    job.setJobGroup(jobKey.getGroup());
                    job.setJobClassName(jobDetail.getJobClass().getName());
                    job.setTriggerName("触发器:" + trigger.getKey());
                    job.setJobDataMap(jobMap);
                    job.setDescription(jobDetail.getDescription());
                    job.setJobDataMapList(jobDataMapList);
                    Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
                    job.setTriggerState(triggerState.name());
                    if (trigger instanceof CronTrigger) {
                        CronTrigger cronTrigger = (CronTrigger) trigger;
                        String cronExpression = cronTrigger.getCronExpression();
                        job.setCronExpression(cronExpression);
                    }/*else if(trigger instanceof SimpleTrigger){
                        SimpleTrigger simpleTrigger = (SimpleTrigger) trigger;
						long milliseconds = simpleTrigger.getRepeatInterval();
						job.setTimeValue((int) (milliseconds/1000));
					}*/
                    jobList.add(job);
//                    jobMap.clear();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.ok(jobList);
    }

    @PostMapping("/trigger")
    @ApiOperation(value = "触发定时任务", notes = "触发指定的定时任务")
    @ApiImplicitParam(name = "quartz", value = "定时任务实体类", required = true, dataType = "QuartzEntity")
    public Result trigger(QuartzEntity quartz, HttpServletResponse response) {
        LOGGER.info("触发任务");
        try {
            JobKey key = new JobKey(quartz.getJobName(), quartz.getJobGroup());
            scheduler.triggerJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }

    @PostMapping("/pause")
    @ApiOperation(value = "暂停定时任务", notes = "暂停指定的定时任务")
    @ApiImplicitParam(name = "quartz", value = "定时任务实体类", required = true, dataType = "QuartzEntity")
    public Result pause(QuartzEntity quartz, HttpServletResponse response) {
        LOGGER.info("停止任务");
        try {
            JobKey key = new JobKey(quartz.getJobName(), quartz.getJobGroup());
            scheduler.pauseJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }

    @PostMapping("/resume")
    @ApiOperation(value = "恢复定时任务", notes = "恢复指定的定时任务")
    @ApiImplicitParam(name = "quartz", value = "定时任务实体类", required = true, dataType = "QuartzEntity")
    public Result resume(QuartzEntity quartz, HttpServletResponse response) {
        LOGGER.info("恢复任务");
        try {
            JobKey key = new JobKey(quartz.getJobName(), quartz.getJobGroup());
            scheduler.resumeJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }

    @PostMapping("/remove")
    @ApiOperation(value = "移除定时任务", notes = "移除指定的定时任务")
    @ApiImplicitParam(name = "quartz", value = "定时任务实体类", required = true, dataType = "QuartzEntity")
    public Result remove(QuartzEntity quartz, HttpServletResponse response) {
        LOGGER.info("移除任务");
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(quartz.getJobName(), quartz.getJobGroup());
            // 停止触发器  
            scheduler.pauseTrigger(triggerKey);
            // 移除触发器  
            scheduler.unscheduleJob(triggerKey);
            // 删除任务  
            scheduler.deleteJob(JobKey.jobKey(quartz.getJobName(), quartz.getJobGroup()));
            System.out.println("removeJob:" + JobKey.jobKey(quartz.getJobName()));
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error();
        }
        return Result.ok();
    }
}
